package com.lida.study.common.utils.tess4j;

import com.lida.study.common.Constants;
import com.lida.study.sudo.Sudo;
import lombok.extern.slf4j.Slf4j;
import net.sourceforge.tess4j.ITessAPI;
import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.Word;

import javax.imageio.ImageIO;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @author lD
 * @date 2019/7/1011:21
 */
@Slf4j
public class Tess4jUtils {

    private Tess4jUtils(){}


    private static ITesseract instance;

    static {
        // 初始化tess4j
        Tess4jUtils.instance = new Tesseract();
        Tess4jUtils.instance.setDatapath(new File(Constants.DATA_PATH).getPath());
    }

    /**
     * 取词方法
     *
     * @throws IOException
     */
    public static Sudo getWords() throws IOException {
        //设置语言库
        instance.setDatapath(Constants.TESS_RESOURCES_LANGUAGE_PATH);
        instance.setLanguage("eng");

        //按照每个字取词
        return createSudo(instance.getWords(ImageIO.read(new File(Constants.TEMP_RESOURCES_DATA_PATH, "temp.jpg")),
                ITessAPI.TessPageIteratorLevel.RIL_SYMBOL));
    }

    /**
     * 确定出数独的整体范围
     * @param words
     * @return
     */
    public static Sudo createSudo(List<Word> words) {
        // 根据识别出的数字的坐标来确定数的位置
        int minx = Integer.MAX_VALUE;
        int miny = Integer.MAX_VALUE;
        int maxx = Integer.MIN_VALUE;
        int maxy = Integer.MIN_VALUE;
        // 确定数独范围
        for (Word word : words) {
            Rectangle rec = word.getBoundingBox();
            int x = (int) rec.getX();
            int y = (int) rec.getY();
            String text = word.getText();
            if (!Pattern.matches("\\d", text)) {
                continue;
            }
            if (!"1".equals(text)) {
                if (x < minx) {
                    minx = x;
                }
                if (y < miny) {
                    miny = y;
                }
                if (x > maxx) {
                    maxx = x;
                }
                if (y > maxy) {
                    maxy = y;
                }
            }
        }
        return getSudo(minx, miny, maxx, maxy, words);
    }

    /**
     * 根据数独的范围确定个数字的位置，从而建立一个数独
     * @param minx
     * @param miny
     * @param maxx
     * @param maxy
     * @param words
     * @return
     */
    public static Sudo getSudo(int minx, int miny, int maxx, int maxy, List<Word> words) {
        // 数独之间的距离
        int arex = (maxx - minx) / 8;
        int arey = (maxy - miny) / 8;
        // 将数独放入对应位置
        Sudo sudo = new Sudo(9);
        for (Word word : words) {
            Rectangle rec = word.getBoundingBox();
            int x = (int) rec.getX();
            int y = (int) rec.getY();
            String text = word.getText();
            // 这里最大X坐标延伸5，是因为最右边的正常数字1的X坐标比其他数字要大一点
            if (x < minx || y < miny || x > (maxx + 5) || y > maxy) {
                continue;
            }
            if (Pattern.matches("\\d", text)) {
                sudo.set((int) Math.round((x - minx) / (double) arex), (int) Math.round((y - miny) / (double) arey), Integer.parseInt(text));
            }
        }
        log.debug("discern result：");
        log.debug(sudo.toString());
        return sudo;
    }
}
